#include "fedonecommunicationmanager.h"

FedOneCommunicationManager::FedOneCommunicationManager(WaveListModel *wlm, ARBlipArray *arba)
{
    m_waveListModel = wlm;
    m_ARBlips = arba;
    QString profile = "QWaveClient";
    m_environment = new Environment(profile);
}

FedOneCommunicationManager::~FedOneCommunicationManager()
{
    //???
}

void FedOneCommunicationManager::login(QString serverAddress, QString username, QString password, int port)
{
    Settings *s = m_environment->settings();
    s->setServerName( serverAddress );
    s->setServerPort( port );
    s->setUserName( username );
    s->setUserAddress( username );
    s->setPassword( password );
    //this will attempt a connection
    m_environment->configure();
    connect(m_environment->inbox(), SIGNAL(waveAdded(Wave *)), this, SLOT(enviroment_waveAdded(Wave *)));
}

void FedOneCommunicationManager::logout()
{
    //TODO
}

void FedOneCommunicationManager::openWavelet(QString waveletId)
{
    Wave *wave = m_wavesMap.value( waveletId );
    m_environment->networkAdapter()->openWavelet( wave->wavelet() );
    m_currentWavelet = wave->wavelet();
    connect(m_currentWavelet, SIGNAL(conversationChanged()), this, SLOT(wavelet_conversationChanged()));
    connect(m_currentWavelet->processor(), SIGNAL(documentMutation(QString,DocumentMutation,QString)), m_currentWavelet, SLOT(mutateDocument(QString,DocumentMutation,QString)));
    //connect(m_currentWavelet, SIGNAL(blipCountChanged()), this, SLOT(wavelet_conversationChanged()));
}

void FedOneCommunicationManager::wavelet_conversationChanged()
{
    QList<Blip*> blips = m_currentWavelet->rootBlips();
    m_ARBlips->clear();
    for(int i = 0; i < blips.size(); i++)
    {
        QString blipText = blips.at(i)->document()->toPlainText();//->toString(); <-- that's a formatted thing, like html, or maybe actual html...
        if( blipText != "" )
        {
            ARBlip *newARBlip = new ARBlip();
            newARBlip->loadFromString( blipText );
            newARBlip->setReferanceID( blips.at(i)->id().toLatin1() );
            m_ARBlips->addBlip( *newARBlip );
            connect(blips.at(i), SIGNAL(update(DocumentMutation)), this, SLOT(blip_updated(DocumentMutation)));
            qDebug("Adding a blip " + blipText.toLatin1());
        }
    }
    emit ARBlipsUpdated();
}

void FedOneCommunicationManager::closeWavelet()
{
    //TODO
}

void FedOneCommunicationManager::createWave(QString title)
{
    QString rand;
    rand.setNum( qrand() );
    Wave *wave = m_environment->createWave( m_environment->settings()->waveDomain(), "w+" + rand);
    m_environment->inbox()->addWave(wave);
    Wavelet* wavelet = wave->wavelet();

    wavelet->processor()->setSuspendSending(true);

    // Tell the server about the new wave
    wavelet->processor()->handleSendAddParticipant(m_environment->localUser());
    //wavelet->processor()->handleSendAddParticipant(p);

    DocumentMutation m1;
    m1.insertStart("conversation");
    QHash<QString,QString> map;
    map["id"] = "b+b1";
    m1.insertStart("blip", map);
    m1.insertEnd();
    m1.insertEnd();
    wavelet->processor()->handleSend( m1, "conversation" );

    DocumentMutation m2;
    // WaveSandBox crashes when this is enabled
    // map.clear();
    // map["name"] = m_environment->localUser()->address();
    // m2.insertStart("contributor", map);
    // m2.insertEnd();
    map.clear();
    m2.insertStart("body", map);
    m2.insertStart("line", map);
    //this is not from the std code
    m2.insertChars(title);
    //this is, instead
    m2.insertEnd();
    m2.insertEnd();
    wavelet->processor()->handleSend( m2, "b+b1" );

    wavelet->processor()->setSuspendSending(false);

    //m_inboxView->select(wave);
}

void FedOneCommunicationManager::enviroment_waveAdded(Wave *wave)
{
    //keep a list of waves with relative ids
    m_wavesMap.insert(wave->id(), wave);

    //get the last existing row
    int lastRow = m_waveListModel->rowCount(QModelIndex());
    //add a new row at the end of the list
    m_waveListModel->insertRows( m_waveListModel->rowCount(QModelIndex()), 1); //insert just one row
    //create a new waveModel object
    WaveModel *waveModel = new WaveModel( wave->id(), QDateTime::currentDateTime(), wave->digest()->toPlainText());
    QVariant newWave;
    newWave.setValue(waveModel);
    //get the index of the last added element
    QModelIndex modelIndex = m_waveListModel->index( lastRow, 0, QModelIndex());
    //put the new wave at the right place
    m_waveListModel->setData(modelIndex, newWave, Qt::EditRole);
}

void FedOneCommunicationManager::addARBlip(QString text)
{
    //m_currentWavelet->rootBlips().last()->createFollowUpBlip("");//text);

    if ( m_currentWavelet->rootBlips().last()->isLastBlipInThread() )
        m_currentWavelet->rootBlips().last()->createFollowUpBlip();
    else
        m_currentWavelet->rootBlips().last()->createReplyBlip();
    /*
    DocumentMutation m1;
    m1.insertStart("conversation");
    QHash<QString,QString> map;
    map["id"] = "b+b1234";
    m1.insertStart("blip", map);
    m1.insertEnd();
    m1.insertEnd();
    m_currentWavelet->processor()->handleSend( m1, "conversation" );

    DocumentMutation m2;
    // WaveSandBox crashes when this is enabled
    // map.clear();
    // map["name"] = m_environment->localUser()->address();
    // m2.insertStart("contributor", map);
    // m2.insertEnd();
    map.clear();
    m2.insertStart("body", map);
    m2.insertStart("line", map);
    m2.insertEnd();
    m2.insertEnd();
    m_currentWavelet->processor()->handleSend( m2, "b+b1234" );
    */
}

void FedOneCommunicationManager::blip_updated(DocumentMutation)
{
    //cast the signalling blip
    Blip *blip = static_cast<Blip *>(sender());
    //crate a new arblip from the blip
    ARBlip *newARBlip = new ARBlip();
    //fill arblip infos
    newARBlip->loadFromString( blip->document()->toPlainText() );
    //set arblip id (same as blip id)
    newARBlip->setReferanceID( blip->id().toLatin1() );
    //add (or replace) the new blip
    m_ARBlips->addBlip( *newARBlip );

    //notify the rest of the world
    emit ARBlipsUpdated();
}

void FedOneCommunicationManager::updateARBlip(QByteArray blipID, QString text)
{
    //get the blip by id
    //m_currentWavelet
}

void FedOneCommunicationManager::deleteARBlip(QByteArray blipID)
{
    //TODO. can this be done?
}

bool FedOneCommunicationManager::addParticipant(QString participant)
{
    //TODO
    return false;
}
